﻿using System.Linq;
using System.Web.Mvc;
using LERP.Domain;
using LERP.Domain.Enums;
using LERP.Web.App_Start;
using Sharp.Framework.Queries;

namespace LERP.Web
{
    public class UserAuthorizeAttribute : AuthorizeAttribute
    {

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var identity = filterContext.HttpContext.User.Identity;
            if (identity.IsAuthenticated)
            {
                var userId = int.Parse(filterContext.HttpContext.User.Identity.Name);
                var controller = filterContext.RouteData.Values["controller"].ToString();
                var action = filterContext.RouteData.Values["action"].ToString();
                string method = filterContext.HttpContext.Request.HttpMethod;
                var isAllowed = IsAllowed(userId, controller, action, method);

                if (!isAllowed)
                {
                    filterContext.Result = new ViewResult { ViewName = "Unauthorized" };
                }

            }

        }

        private bool IsAllowed(int userid, string controller, string action, string method)
        {
            var allActions = FunctionConfigManger.AllActions;
            if (allActions.Any(
                m => m.Contrller.ToLower() == controller.ToLower() && m.Name.ToLower() == action.ToLower() &&
                     (m.Method == "all" || m.Method.ToLower() == method.ToLower())))
            {
                var query = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IQuery>();
                var user = query.Get<User>(userid);
                if (user.Role != UserRole.System)
                {
                    var functionId = user.Functions;

                    var actions = FunctionConfigManger.GetActions(functionId);
                    return
                        actions.Any(
                            m =>
                            m.Contrller.ToLower() == controller.ToLower() && m.Name.ToLower() == action.ToLower() &&
                            (m.Method == "all" || m.Method.ToLower() == method.ToLower()));

                }
            }
            return true;
        }
    }
}